home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
L' Effet Pommier 3
/
L'Effet Pommier - Volume 03.iso
/
Programmation
/
gray image 2.1
/
vfilter.cc
< prev
next >
Wrap
Text File
|
1995-05-03
|
15KB
|
415 lines
// This may look like C code, but it is really -*- C++ -*-
/*
************************************************************************
*
* Grayscale Image
*
* Verify image filtration and related functions
*
* $Id: vfilter.cc,v 2.0 1995/03/18 18:19:06 oleg Exp oleg $
*
************************************************************************
*/
#include "filter.h"
#include <iostream.h>
static IMAGE Test_image(16,31,8); //(256,512,8);
/*
*----------------------------------------------------------------------
* Make sure that Test_image is what we've expected
*/
static void verify_identity(const IMAGE& test_image, const IMAGE& ethalon)
{
if( test_image == ethalon )
return;
compare(test_image,ethalon,"test image is different from ethalon");
test_image.print("Test image");
ethalon.print("ethalon");
_error("Something fishy is going on here... look into this...");
}
/*
*----------------------------------------------------------------------
* Testing convolutions
*/
static void test_convolutions(void)
{
cout << "\nVerify convolutions of an image" << endl;
const int seed = 137;
IMAGE expected(Test_image);
{
cout << "\thomogenious image should stay the same (or similar)" << endl;
Test_image = seed;
verify_pixel_value(FilterIt(Test_image).
conv(conv_kernel(1,2,3),FilterIt::Rows),
(1+2+3)*seed);
verify_pixel_value(FilterIt(Test_image=seed).
conv(conv_kernel(1,2,3),FilterIt::Columns),
(1+2+3)*seed);
verify_pixel_value(FilterIt(Test_image=seed).
conv(conv_kernel(1,2,3)),
(1+2+3)*(1+2+3)*seed);
verify_pixel_value(FilterIt(Test_image=seed).
conv_row(conv_kernel(1,2,1,over_2_up(2))),
seed);
verify_pixel_value(FilterIt(Test_image=seed).
conv_col(conv_kernel(4,8,4,over_2_up(3))),
2*seed);
verify_pixel_value(FilterIt(Test_image=seed).
conv(conv_kernel(0,2,6,CommonDenom(2)),FilterIt::Rows),
4*seed);
verify_pixel_value(FilterIt(Test_image=seed).
conv(conv_kernel(1,2,3,CommonDenom(6))),
seed);
}
{
cout << "\tTest filtering a single vertical line" << endl;
IMAGE vert_line(Test_image);
vert_line = 0;
vert_line.rectangle(rowcol(0,vert_line.q_ncols()/2),
rowcol(vert_line.q_nrows()-1,
vert_line.q_ncols()/2)) = -seed;
Test_image = vert_line;
verify_identity(FilterIt(Test_image).
conv(conv_kernel(1,2,1),FilterIt::Columns)>>=2,vert_line);
verify_identity(FilterIt(Test_image).
conv_col(conv_kernel(1,2,3,CommonDenom(6))),vert_line);
verify_identity(FilterIt(Test_image).
conv(conv_kernel(0,2,0,over_2_up(1))),vert_line);
expected = 0;
expected.rectangle(rowcol(0,vert_line.q_ncols()/2-1),
rowcol(vert_line.q_nrows()-1,
vert_line.q_ncols()/2+1)) = -seed;
verify_identity(FilterIt(Test_image=vert_line).
conv(conv_kernel(1,1,1),FilterIt::Rows),expected);
}
{
cout << "\tTest filtering a single horizontal line" << endl;
IMAGE hor_line(Test_image);
hor_line = 1;
hor_line.rectangle(rowcol(hor_line.q_nrows()/2-1,0),
rowcol(hor_line.q_nrows()/2-1,
hor_line.q_ncols()-1)) = seed;
Test_image = hor_line;
verify_identity(FilterIt(Test_image).
conv(conv_kernel(1,2,1,over_2_up(2)),FilterIt::Rows),
hor_line);
verify_identity(FilterIt(Test_image).
conv_row(conv_kernel(3,2,1,CommonDenom(6))),hor_line);
verify_identity(FilterIt(Test_image).
conv(conv_kernel(0,3,0,CommonDenom(3))),hor_line);
Test_image = hor_line;
expected = hor_line(0,0);
expected.rectangle(rowcol(hor_line.q_nrows()/2-2,0),
rowcol(hor_line.q_nrows()/2-2,
hor_line.q_ncols()-1)) = (3*seed+3)/6;
expected.rectangle(rowcol(hor_line.q_nrows()/2-1,0),
rowcol(hor_line.q_nrows()/2-1,
hor_line.q_ncols()-1)) = (2*seed+4)/6;
expected.rectangle(rowcol(hor_line.q_nrows()/2,0),
rowcol(hor_line.q_nrows()/2,
hor_line.q_ncols()-1)) = (seed+5)/6;
verify_identity(FilterIt(Test_image=hor_line).
conv(conv_kernel(1,2,3,CommonDenom(6)),FilterIt::Columns),
expected);
}
{
cout << "\tTest filtering (phase shifting) a small 2x2 square" << endl;
const card sq_row = Test_image.q_nrows()/3;
const card sq_col = (2*Test_image.q_ncols())/3;
IMAGE small_sq(Test_image);
small_sq = 1;
small_sq(sq_row,sq_col) = seed; small_sq(sq_row,sq_col+1) = seed+1;
small_sq(sq_row+1,sq_col) = seed+1; small_sq(sq_row+1,sq_col+1) = seed;
verify_identity(FilterIt(Test_image=small_sq).
conv(conv_kernel(0,1,0)),small_sq);
expected = small_sq; expected >>=2;
verify_identity(FilterIt(Test_image).
conv(conv_kernel(0,2,0,CommonDenom(4))),expected);
expected = small_sq(0,0);
expected.square_of(2,rowcol(sq_row+1,sq_col+1)) =
small_sq.square_of(2,rowcol(sq_row,sq_col));
verify_identity(FilterIt(Test_image=small_sq).
conv(conv_kernel(1,0,0)),expected);
expected = small_sq(0,0);
expected.square_of(2,rowcol(sq_row-1,sq_col-1)) =
small_sq.square_of(2,rowcol(sq_row,sq_col));
verify_identity(FilterIt(Test_image=small_sq).
conv(conv_kernel(0,0,2,over_2_up(1))),expected);
}
cout << "\nDone" << endl;
}
/*
*----------------------------------------------------------------------
* Testing median filtration
*/
static void test_median_filtration(void)
{
cout << "\nVerify median filtration of an image" << endl;
const int seed = 141;
IMAGE expected(Test_image);
cout << "\thomogenious image should stay the same" << endl;
Test_image = seed; expected = Test_image;
verify_identity(FilterIt(Test_image).median(FilterIt::RowsAndColumns),
expected);
verify_identity(FilterIt(Test_image).median(FilterIt::RowsAndColumns,5),
expected);
cout << "\t1-pixel speckle should be filtered out" << endl;
Test_image = seed; Test_image(4,4) = 0;
verify_pixel_value(FilterIt(Test_image).median(FilterIt::Rows),seed);
Test_image(4,4) = 0;
verify_pixel_value(FilterIt(Test_image).median(FilterIt::Columns),seed);
Test_image(4,4) = 0;
verify_pixel_value(FilterIt(Test_image).median(FilterIt::Rows,5),seed);
Test_image(4,4) = 0;
verify_pixel_value(FilterIt(Test_image).median(FilterIt::Columns,5),seed);
Test_image(4,4) = 0; Test_image ^= (~0);
expected = Test_image; expected(4,4) = expected(0,0);
verify_pixel_value(FilterIt(Test_image).median(FilterIt::Columns),seed ^ ~0);
Test_image = seed; Test_image(4,4) = 0; Test_image ^= (~0);
verify_pixel_value(FilterIt(Test_image).median(FilterIt::Columns,5),
seed ^ ~0);
{
cout << "\tTest filtering a single vertical line" << endl;
IMAGE vert_line(Test_image);
vert_line = 0;
vert_line.rectangle(rowcol(0,vert_line.q_ncols()/2),
rowcol(vert_line.q_nrows()-1,
vert_line.q_ncols()/2)) = -seed;
Test_image = vert_line;
verify_identity(FilterIt(Test_image).median(FilterIt::Columns),vert_line);
verify_identity(FilterIt(Test_image).median(FilterIt::Columns,5),
vert_line);
Test_image = vert_line;
expected = vert_line(0,0);
verify_identity(FilterIt(Test_image).median(FilterIt::Rows,3),expected);
Test_image = vert_line;
verify_identity(FilterIt(Test_image).median(FilterIt::Rows,5),expected);
}
{
cout << "\tTest filtering a single horizontal line" << endl;
IMAGE hor_line(Test_image);
hor_line = ~0;
hor_line.rectangle(rowcol(hor_line.q_nrows()/2-1,0),
rowcol(hor_line.q_nrows()/2-1,
hor_line.q_ncols()-1)) = seed;
Test_image = hor_line;
verify_identity(FilterIt(Test_image).median(FilterIt::Rows),hor_line);
verify_identity(FilterIt(Test_image).median(FilterIt::Rows,5),hor_line);
Test_image = hor_line;
expected = hor_line(0,0);
verify_pixel_value(FilterIt(Test_image).median(FilterIt::Columns,3),
hor_line(0,0));
Test_image = hor_line;
verify_identity(FilterIt(Test_image).median(FilterIt::Columns,5),expected);
}
{
cout << "\tBorder outlines should stay the same" << endl;
const int nrows = Test_image.q_nrows();
const int ncols = Test_image.q_ncols();
Test_image = 0;
Test_image.rectangle(rowcol(0,0),rowcol(nrows-1,0)) = seed;
Test_image.rectangle(rowcol(1,1),rowcol(nrows-2,1)) = seed-1;
Test_image.rectangle(rowcol(0,ncols-1),rowcol(nrows-1,ncols-1)) = seed;
Test_image.rectangle(rowcol(1,ncols-2),rowcol(nrows-2,ncols-2)) = seed-1;
Test_image.rectangle(rowcol(0,0),rowcol(0,ncols-1)) = seed;
Test_image.rectangle(rowcol(1,1),rowcol(1,ncols-2)) = seed-1;
Test_image.rectangle(rowcol(nrows-1,0),rowcol(nrows-1,ncols-1)) = seed;
Test_image.rectangle(rowcol(nrows-2,1),rowcol(nrows-2,ncols-2)) = seed-1;
expected = Test_image;
verify_identity(FilterIt(Test_image).median(FilterIt::RowsAndColumns,3),
expected);
verify_identity(FilterIt(Test_image).median(FilterIt::RowsAndColumns,5),
expected);
}
{
cout << "\tTest filtering a small 2x2 square" << endl;
const card sq_row = Test_image.q_nrows()/3;
const card sq_col = (2*Test_image.q_ncols())/3;
IMAGE small_sq(Test_image);
small_sq = 1;
small_sq(sq_row,sq_col) = seed; small_sq(sq_row,sq_col+1) = seed+1;
small_sq(sq_row+1,sq_col) = seed+1; small_sq(sq_row+1,sq_col+1) = seed;
expected = small_sq; expected.square_of(2,rowcol(sq_row,sq_col)) = seed;
verify_identity(FilterIt(Test_image=small_sq).median(FilterIt::Columns,3),
expected);
verify_identity(FilterIt(Test_image=small_sq).median(FilterIt::Rows,3),
expected);
verify_identity(FilterIt(Test_image=small_sq).
median(FilterIt::RowsAndColumns,3),expected);
verify_pixel_value(FilterIt(Test_image=small_sq).
median(FilterIt::Columns,5),expected(0,0));
verify_pixel_value(FilterIt(Test_image=small_sq).
median(FilterIt::Rows,5),expected(0,0));
verify_pixel_value(FilterIt(Test_image=small_sq).
median(FilterIt::RowsAndColumns,5),expected(0,0));
}
{
cout << "\tTest filtering a bigger 4x4 square" << endl;
const card sq_row = (2*Test_image.q_nrows())/3;
const card sq_col = Test_image.q_ncols()/3;
IMAGE med_sq(Test_image);
med_sq = seed;
med_sq.square_of(4,rowcol(sq_row,sq_col)) = 1;
med_sq(sq_row,sq_col+2) = 2;
verify_identity(FilterIt(Test_image=med_sq).median(FilterIt::Columns,3),
med_sq);
expected = med_sq; expected(sq_row,sq_col+2) = 1;
expected(sq_row,sq_col+3) = 2;
verify_identity(FilterIt(Test_image=med_sq).median(FilterIt::Rows,3),
expected);
verify_identity(FilterIt(Test_image=med_sq).
median(FilterIt::RowsAndColumns,3),expected);
verify_identity(FilterIt(Test_image=med_sq).median(FilterIt::Columns,5),
med_sq);
expected = med_sq;
expected(sq_row,sq_col+2) = 1;
expected(sq_row,sq_col) = 2; expected(sq_row,sq_col+3) = 2;
verify_identity(FilterIt(Test_image=med_sq).median(FilterIt::Rows,5),
expected);
verify_identity(FilterIt(Test_image=med_sq).
median(FilterIt::RowsAndColumns,5),expected);
}
cout << "\nDone\n";
}
/*
*------------------------------------------------------------------------
* Testing table look-ups
*/
static void test_lookups(void)
{
cout << "\nVerify table lookups" << endl;
const int min_seed = -2;
IMAGE diverse_image(Test_image); // With all values -2:no_pixels
{
class MakeDiverse : public PixelPrimAction
{
GRAY_SIGNED curr;
void operation(GRAY& pixel) { pixel = curr++; }
public: MakeDiverse(const GRAY_SIGNED seed) : curr(seed) {}
};
diverse_image.apply(MakeDiverse(min_seed));
}
IMAGE expected(Test_image);
LookupT Identical(LookupT::Identical(Test_image.q_depth()));
{
cout << "\ttest applying identical LookupT" << endl;
verify_identity(FilterIt(Test_image=diverse_image).
translate(Identical,LookupT::LeaveFringes),
diverse_image);
LookupT another_identical(Identical);
another_identical.apply(Identical,LookupT::LeaveFringes);
verify_identity(FilterIt(Test_image=diverse_image).
translate(another_identical,LookupT::LeaveFringes),
diverse_image);
another_identical.apply(Identical,LookupT::CoerceFringes);
verify_identity(FilterIt(Test_image=diverse_image).
translate(another_identical,LookupT::LeaveFringes),
diverse_image);
cout << "\tCoercing during translation should be the same as "
"clip_to_intensity_range()" << endl;
assert( !(diverse_image >= 0) ); // Make sure we have smth to
assert( !(diverse_image < (1<<diverse_image.q_depth())) ); // clip from
(expected = diverse_image).clip_to_intensity_range();
verify_identity(FilterIt(Test_image).
translate(Identical,LookupT::CoerceFringes),
expected);
}
{
cout << "\ttest applying one pixel mapping LookupT" << endl;
const GRAY seed = 4;
assert( !(diverse_image != seed) ); // make sure we have this pixel
LookupT map(LookupT::MapTo(seed,seed+1));
assert( FilterIt(Test_image=diverse_image).
translate(map,LookupT::LeaveFringes) != seed );
// const GRAY seed1 = -2;
const GRAY seed1 = diverse_image.q_npixels()-2-1;
assert( !(diverse_image != seed1) ); // make sure we have this pixel
assert( diverse_image != seed1+1 );
LookupT map1(LookupT::MapTo(seed1,seed1+1));
assert( FilterIt(Test_image=diverse_image).
translate(map1,LookupT::LeaveFringes) != seed1 );
assert( !(Test_image != seed1+1) ); // Now we have seed-1
cout << "\tCoercing during translation should make all pixels the same"
<< endl;
verify_pixel_value(FilterIt(Test_image=diverse_image).
translate(map,LookupT::CoerceFringes),seed+1);
verify_pixel_value(FilterIt(Test_image=diverse_image).
translate(map1,LookupT::CoerceFringes),seed1+1);
map.apply(Identical,LookupT::CoerceFringes);
verify_pixel_value(FilterIt(Test_image=diverse_image).
translate(map,LookupT::CoerceFringes),seed+1);
LookupT another_map = Identical;
another_map.apply(map,LookupT::CoerceFringes);
verify_pixel_value(FilterIt(Test_image=diverse_image).
translate(another_map,LookupT::CoerceFringes),seed+1);
}
{
cout << "\ttest inverting an image via LookupT" << endl;
LookupT invert(Identical);
for(register GRAY i=invert.q_min(); i<=invert.q_max(); i++)
invert[i] ^= ((1<<diverse_image.q_depth())-1);
(expected = diverse_image).clip_to_intensity_range().invert();
verify_identity(FilterIt(Test_image=diverse_image).
translate(invert,LookupT::CoerceFringes),
expected);
}
cout << "\nDone\n";
}
/*
*------------------------------------------------------------------------
* The testing routing module
*/
main()
{
test_median_filtration();
test_convolutions();
test_lookups();
}